#!/usr/bin/perl

#  VGA Planets Game Display CGI for the VGAPd Thingy
#  Copyright (C) 2004 Peter Burns
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License version 2 as
#  published by the Free Software Foundation.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#  This program is currently hosted at http://code.google.com/p/vgapd/

use strict;
use warnings;
use Config::IniFiles;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use CGI::Pretty;
use VGAP::Tools;
use Switch;
$main::TZ='EST5EDT';
use Date::Manip;


## Variable Declaration
my $VERSION = "0.2";
our %cgiini;
our %ini;
our %RaceNames;
our @days;
our $query = new CGI;


####################
### Sub Routines ###
####################

sub InitMain() {
   my $count;

   if (!-e "vgap_games.ini") {
     die("Error! Cannot locate INI file.");
   } else {
     tie %cgiini, 'Config::IniFiles', (-file =>"vgap_games.ini");
   }

   if (!-e "$cgiini{General}{VgapdDir}/vgapd.ini") {
      die("Error! Directory $cgiini{General}{VgapdDir} does not exist or no vgapd.ini file found there.\n");
   }

   if (!-r "$cgiini{General}{VgapdDir}/vgapd.ini") {
      die("Error! $cgiini{General}{VgapdDir}/vgapd.ini exists but it doesn't seem to be readable.\n");
   }

   tie %{$ini{main}}, 'Config::IniFiles', ( -file => "$cgiini{General}{VgapdDir}/vgapd.ini");
   for ($count = 1; $count <= $ini{main}{General}{NumberOfGames}; $count++) {
      tie %{$ini{"Game$count"}}, 'Config::IniFiles', ( -file => $ini{main}{GameINI}{"Game$count"});
   }

   for ($count = 1; $count <= $ini{main}{General}{NumberOfGames}; $count++) {
      @{$RaceNames{"Game$count"}} = VGAP::Tools::GetRaceLongNames($ini{"Game$count"}{General}{Homedir},$ini{"Game$count"}{General}{VGAPdir});
   }

   $days[1] = 'Monday';
   $days[2] = 'Tuesday';
   $days[3] = 'Wednesday';
   $days[4] = 'Thursday';
   $days[5] = 'Friday';
   $days[6] = 'Saturday';
   $days[7] = 'Sunday';
} #End Init sub


sub Cleanup() {
   my $count;

   for ($count = 1; $count <= $ini{main}{General}{NumberOfGames}; $count++) {
      untie %{$ini{"Game$count"}};
   }
   untie %{$ini{main}};
   untie %cgiini;
} #End Cleanup sub


sub GetTurnStatus($$) {
  my $Game = shift;
  my $player = shift;

  if (-e "$ini{$Game}{General}{Homedir}player$player.trn") {
    return "Submitted";
  } elsif (!-e "$ini{$Game}{General}{Homedir}nextturn.hst"
            || -z "$ini{$Game}{General}{Homedir}nextturn.hst")
  {
    return "N/A";
  } else {
    return "Waiting";
  }
} #End GetTurnStatus sub


sub PrintTimScore($) {
  my $Game = shift;
  my @scoretable;
  my @tablerows;
  my $count = 0;

  if (VGAP::Tools::GetTimScore($ini{$Game}{General}{Homedir},\@scoretable)) {
    @tablerows = $query->th([
      $cgiini{TimScore}{Column1},
      $cgiini{TimScore}{Column2},
      $cgiini{TimScore}{Column3},
      $cgiini{TimScore}{Column4},
      $cgiini{TimScore}{Column5},
      $cgiini{TimScore}{Column6}
    ]);

    while (defined($scoretable[$count])){
      push(@tablerows,$query->td($scoretable[$count]));
      $count++;
    }

    print $query->table(
      $query->caption($query->strong($cgiini{TimScore}{Caption})),
      $query->Tr(\@tablerows)
    );
  }

} #End PrintTimScore sub


sub PrintPTScore($) {
  my $Game = shift;
  my @tablerows;
  my %ptscore;
  my $count = 0;
  my $graphfile;

  if (VGAP::Tools::GetPTScore($ini{$Game}{General}{Homedir},\%ptscore)) {
    @tablerows = $query->th([
      $cgiini{PTScore}{Column1},
      $cgiini{PTScore}{Column2},
      $cgiini{PTScore}{Column3},
      $cgiini{PTScore}{Column4},
      $cgiini{PTScore}{Column5},
      $cgiini{PTScore}{Column6},
      $cgiini{PTScore}{Column7},
      $cgiini{PTScore}{Column8},
      $cgiini{PTScore}{Column9},
      $cgiini{PTScore}{Column10},
      $cgiini{PTScore}{Column11},
      $cgiini{PTScore}{Column12},
      $cgiini{PTScore}{Column13}
    ]);

    while (defined($ptscore{scoretable}[$count])){
      $graphfile = "$ini{$Game}{General}{ShortName}/race$ptscore{scoretable}[$count][0].data.png";
      if (-e "$cgiini{General}{GraphBaseDir}/$graphfile") {
        $ptscore{scoretable}[$count][1] = $query->a({-href=>"$cgiini{General}{GraphBaseURL}/$graphfile",-target=>'_new'},$ptscore{scoretable}[$count][1]);
      }
      push(@tablerows,$query->td($ptscore{scoretable}[$count]));
      $count++;
    }

    print $query->table(
      $query->caption($query->strong($cgiini{PTScore}{Caption})),
      $query->Tr(\@tablerows)
    );
    if (-e "$cgiini{General}{GraphBaseDir}/$ini{$Game}{General}{ShortName}/global.png") {
      print $query->p();
      print $query->strong($query->a({-href=>"$cgiini{General}{GraphBaseURL}/$ini{$Game}{General}{ShortName}/global.png",-target=>'_new'},$cgiini{PTScore}{GlobalGraph})).$query->br();
    }
    print $query->p();
    print $query->strong("Ship Slots: ").$ptscore{used}." used, ".$ptscore{empty}." empty.".$query->br();
    print $query->strong("PTScore version: ").$ptscore{version}.$query->br();
  }

} #End PrintPTScore sub


sub PrintGameStatus($) {
  my $Game = shift;
  my $count;
  my @rows;
  my @columns;
  my $turnstatus;
  my @lastsubmitted;
  my $data;

  if (-e "$ini{$Game}{General}{Homedir}lastin.dat"
      && -r "$ini{$Game}{General}{Homedir}lastin.dat")
  {
    open (FILE, $ini{"$Game"}{General}{Homedir}.'lastin.dat')
      or die("Failed to open $ini{$Game}{General}{Homedir}lastin.dat\n");
    $data = <FILE>;
    close FILE;
    chomp($data);
    if (defined($data)) {
      @lastsubmitted = split(/:/,$data);
    }
  }

  for ($count = 1; $count <= 11; $count++) {
    if ($count == 1) {
      push(@columns,$cgiini{GameStatus}{Column1});
      push(@columns,$cgiini{GameStatus}{Column2});
      push(@columns,$cgiini{GameStatus}{Column3});
      if (uc($ini{$Game}{General}{HiddenPlayers}) eq "NO") {
        push(@columns,$cgiini{GameStatus}{Column4});
      }
      if (-e "$ini{$Game}{General}{Homedir}lastin.dat"
          && -r "$ini{$Game}{General}{Homedir}lastin.dat")
      {
        push(@columns,$cgiini{GameStatus}{Column5});
      }

      @rows = $query->th(\@columns);
    }
    undef @columns;
    if ($ini{"$Game"}{"Player$count"}{Active} eq "YES") {
      $turnstatus = GetTurnStatus($Game,$count);
      push(@columns,$count);
      push(@columns,$RaceNames{"$Game"}[($count - 1)]);
      if ($turnstatus eq "Waiting") {
        push(@columns,$query->b($query->font({-color=>"red"},$turnstatus)));
      } else {
        push(@columns,$turnstatus);
      }
      if (uc($ini{$Game}{General}{HiddenPlayers}) eq "NO") {
        my $playerid = $ini{$Game}{"Player$count"}{Email};
        $playerid =~ s/@.*$//;
        push(@columns,$playerid);
      }
      push(@columns,($lastsubmitted[($count - 1)] - 1)) if (@lastsubmitted);

      push(@rows,$query->td(\@columns));
    }

  }
  print $query->table(
    $query->caption($query->strong($cgiini{GameStatus}{Caption})),
    $query->Tr(\@rows)
  );
} #End PrintGameStatus sub


sub DefaultPage() {
   my $count;
   my @rows;

   print $query->header();
   print $query->start_html(-title=>$cgiini{General}{Title},-style=>{-src=>$cgiini{General}{StyleSheet}});
   print $query->h2("$cgiini{General}{Title}");

   @rows = $query->th([
    $cgiini{GameList}{Column1},
    $cgiini{GameList}{Column2},
    $cgiini{GameList}{Column3},
    $cgiini{GameList}{Column4}
   ]);
   for ($count = 1; $count <= $ini{main}{General}{NumberOfGames}; $count++) {
      push(@rows,$query->td([
         $query->a({href=>"?Page=Game$count"},$ini{"Game$count"}{General}{LongName}),
         $ini{"Game$count"}{General}{ShortName},
         $ini{"Game$count"}{General}{Status},
         VGAP::Tools::GetTurnNumber($ini{"Game$count"}{General}{Homedir})
      ]));
   }

   print $query->table(
         $query->caption($query->strong($cgiini{GameList}{Caption})),
         $query->Tr(\@rows)
   );
   print $query->p($query->a({href=>$cgiini{General}{HomeURL}},$cgiini{General}{HomeTAG}));
   print $query->end_html;
} #End DefaultPage sub


sub GamePage($) {
  my $Game = shift;
  my @exemptdays;
  my $element;
  my $turn = VGAP::Tools::GetTurnNumber($ini{$Game}{General}{Homedir});

  print $query->header();
  print $query->start_html(-title=>"$ini{$Game}{General}{ShortName} VGAPd Game Status",-style=>{-src=>$cgiini{General}{StyleSheet}});
  print $query->h2("$ini{$Game}{General}{LongName}");
  print $query->strong("Short Name: ").$ini{$Game}{General}{ShortName}.$query->br();
  print $query->strong("Status: ").$ini{$Game}{General}{Status}.$query->br();
  print $query->strong('Turn #: ').$turn.$query->br();

  if (ref($ini{$Game}{General}{Description})) {
    print $query->strong("Description:").$query->br();
    foreach $element (@{$ini{$Game}{General}{Description}}) {
      chomp $element;
      $element =~ s/\s*(http:\/\/.+)\s*/<a href="$1">$1<\/a>/g;
      print $element;
      print $query->br();
    }
  } else {
    $element = $ini{$Game}{General}{Description};
    $element =~ s/\s*(http:\/\/.+)\s*/<a href="$1">$1<\/a>/g;
    print $query->strong("Description: ").$element.$query->br();
  }

  print $query->p();
  print $query->strong("Run Frequency: ").$ini{$Game}{Running}{Frequency}.$query->br();
  if (defined($ini{"$Game"}{Running}{Exempt}) && (length($ini{"$Game"}{Running}{Exempt}) != 0)) {
    foreach $element (split(/:/,$ini{$Game}{Running}{Exempt})) {
      push(@exemptdays,$days[$element]);
    }
    print $query->strong("Exempt Days: ").@exemptdays.$query->br();
  }
  if (uc($ini{$Game}{NextRun}{NextRun}) ne "NEVER") {
    print $query->strong("Next Host Run: ").UnixDate(ParseDate($ini{$Game}{NextRun}{NextRun}),"%A, %B the %E at %i:%M%p");
    print ", or as soon as all turns are submitted." if (uc($ini{$Game}{Running}{RunEarly}) eq 'YES');
  }

  print $query->p();
  PrintGameStatus($Game);
  print $query->p();
  PrintTimScore($Game) if ($cgiini{$Game}{DisplayTimScore} ne "NO");
  print $query->p();
  PrintPTScore($Game) if ($cgiini{$Game}{DisplayPTScore} ne "NO");

  print $query->p($query->a({href=>"?"},"Return to Main"));
  print $query->end_html;

} #End GamePage sub


##Start main body
InitMain();

if (!defined($query->param())) {
  DefaultPage();
} elsif (defined($query->param('Page'))) {
  if (defined($ini{$query->param('Page')})) {
    GamePage($query->param('Page'));
  } else {
    DefaultPage();
    warn('Invalid value for Page.\n');
  }
} else {
  warn('Invalid parameter.\n');
  DefaultPage();
}

Cleanup();
##End main body
